Skip to content

20 valid parentheses#6

Open
kitano-kazuki wants to merge 15 commits intomainfrom
20-valid-parentheses
Open

20 valid parentheses#6
kitano-kazuki wants to merge 15 commits intomainfrom
20-valid-parentheses

Conversation

@kitano-kazuki
Copy link
Copy Markdown
Owner

No description provided.

return False
```

## Code3 (再帰)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一応、想像した再帰とは違いました。

再帰下降を見ておいてください。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.5ynll0rwu02h

Copy link
Copy Markdown
Owner Author

@kitano-kazuki kitano-kazuki Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

再帰降下法はあまり馴染み無かったので実装しました
https://github.com/kitano-kazuki/leetcode/pull/6/changes#diff-cf71cdc6c0d746b654ccddf6a975ccbbea929f8e2d2fee0362ccf6e9f5a3def6

でもあまり自信はないです.
お時間あれば, こちらもレビューしていただけますと幸いです.

class Solution:
def isValid(self, s: str) -> bool:
unclosed_brackets = []
brackets_pairs = {
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

命名はopen_to_closeとかにする方が良さそう
https://github.com/kunimomo/leetcode/pull/8/changes#r2771430167

* 再帰降下法の実装をした.
* [参考](https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.5ynll0rwu02h)
* 自然言語で解釈をちゃんとできたらバグなく実装できた.
* ただ, `nonlocal`な変数として処理をしている`idx`を持つのは初見だと思いつかなさそう.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C++ だとリファレンスで idx を与えることもありますね。

カプセル化して、peek (次の文字を見る) consume (次の文字を使う) などの関数を定義するのも一つです。

while processing_idx < len(s):
if not check_chunk_valid():
return False
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

微妙に標準的な再帰下降構文解析とは異なっているように感じます。まあ、別にこれでもいいですが。
標準的なのだと
S -> Chunk S | ε
Chunk -> (S) | {S} | [S]
でしょう。で、parse_s と parse_chunk を両方書けばいいです。
で、最後に return parse_s() and self.pos == len(self.s) します。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なるほど、先に文脈自由文法で考えるとわかりやすいですね。ありがとうございます。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LL(1)の実装もしてみました

再帰降下もLL(1)も1文字先を見て, 適用する構文を決定するという仕組みは一緒なんでしょうか.
だとすると, やっていることは再帰降下と一緒なのに実装コストがLL(1)はとても重く感じました.

それぞれの方法の比較として

  • LL(1)
    • 今回は, left-recrusiveの解消やleft factorizationはしていないが, それをすればどのような文脈自由文法も自然言語として受け取れる.
    • 構文解析と字句解析を切り分けられる ← これがいちばんのメリットっぽい??
  • 再帰降下
    • 人間が解釈して, 先読み文字と適用する構文の関係をコードに組み込む必要がある.
    • 実装はLL(1)に比べて楽
    • 構文解析と字句解析を同時に行う(?)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

少し違和感があります。

文脈自由文法の真部分集合に LL(1) 文法があって、その伝統的なアルゴリズムに再帰下降とテーブル駆動があります。再帰下降はバックトラックなどをつけてもう少し広いクラスを扱うこともあります。

トークナイザーは、ここでは1文字1トークンになっているが、別にすることは可能です。

テーブル駆動の利点は、コードの自動生成が簡単ということですね。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

テーブル駆動で解析できるものに関して、あらゆる文脈自由文法という表現は不適でLL(1)文法とするべきでしたね。

テーブル駆動の利点がコードの自動生成が簡単というのは考えが及んでいなかったです。ありがとうございます。

"[" : "]"
}
open_brakets = bracket_pairs.keys()
for i in range(len(s)):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s はイテラブル ( str )ですので、for bracket in s と書くと読みやすいと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確かに今回はiを使ってないので, for bracket in sの方が良さそうです

continue
if len(unclosed_open_brackets) == 0:
return False
last_open_bracket = unclosed_open_brackets.pop(-1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.pop() はデフォルトがリストの最後ですので、.pop(-1)と等価ですね。
https://docs.python.org/3/tutorial/datastructures.html#more-on-lists

list.pop([i])
Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list. It raises an IndexError if the list is empty or the index is outside the list range.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。
半分手癖なんですけど, pop()が末尾からだよってことを明示したくて毎回pop(-1)にしてます.

Comment on lines +154 to +156
if len(unclosed_open_brackets) > 0:
return False
return True
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここはreturn not unclosed_open_bracketsと一行でスッキリ書けます。空のリストは falsy (implicit false) なので。
こちらも参考になると思います。

For sequences (strings, lists, tuples), use the fact that empty sequences are false, so if seq: and if not seq: are preferable to if len(seq): and if not len(seq): respectively.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

スタイルガイドがif seqを推奨だったんですね!知らなかったです。ありがとうございます。

if s[i] in brackets_pairs.keys():
unclosed_brackets.append(s[i])
else:
if len(unclosed_brackets) == 0:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちらのコメントをご参照ください。
mamo3gr/arai60#6 (comment)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。
if not 変数名
とした方が簡潔でいいですね

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants